﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Xml;
using System.IO;

namespace RouterControl.Web
{

    public class ErrorInfo
    {
        public string InstanceGuid;     // used to group error messages by runtime Router Control instance
        public int VersionId;
        public DateTime TimeStampUtc;
        public int Count = 1;

        public string ErrorType;
        public string Message;
        public string ClassName;
        public string MethodName;
        public string StackTrace;
        public string ErrorHash;

        public ErrorInfo Inner;
    }

    public struct ReleaseInfo
    {
        public int ReleaseId;
        public string VersionStr;
        public string MsiDownloadUrl;
        public string ReleaseUrl;
    }

    public class UsageInfo
    {
        public class RouterInfo
        {
            // general support information
            public bool SupportedNative;
            public bool SupportedManaged;

            public string ExitPage;
            public string ErrorMessage;
            public int ErrorCode;

            // router information
            public string RouterSchemaId;
            public string RouterName;
            public string RouterDescription;
            public string RouterModel;
            public string RouterModelNumber;
            public string Manufacturer;
            public string ManufacturerUrl;

            // feature information
            public bool SupportsConnectionSpeed;
            public bool SupportsConnectionStatus;
            public bool SupportsHijackingDetection;
            public bool SupportsTraffic;
            public bool SupportsUptime;
            public bool SupportsPortForwarding;
        }

        // common information
        public Guid InstanceId;
        public int VersionId;
        public string ExitPage;

        // router specific information
        public IList<RouterInfo> Routers = new List<RouterInfo>();

        // system information
        public int FoundRoutersCount;
        public string HomeServerVersion;
        public string UpnpStackVersion;

        // router helper function
        public RouterInfo EnsureRouterInfo(string schemaId, bool forceNew)
        {
            if (string.IsNullOrEmpty(schemaId))
                throw new ArgumentException("null or empty", "schemaId");

            var exists = (
                from r in this.Routers
                where r.RouterSchemaId == schemaId
                select r
                ).FirstOrDefault();

            // drop?
            if ((exists != null) && forceNew)
            {
                this.Routers.Remove(exists);

                exists = null;
            }

            // add?
            if (exists == null)
            {
                exists = new RouterInfo()
                {
                    RouterSchemaId = schemaId
                };

                this.Routers.Add(exists);
            }

            return exists;
        }
    }

    [ServiceContract(Namespace = "http://www.fkollmann.de/RouterControl")]
    public interface IRouterControlWS2
    {
        /// <summary>
        /// uploads a router schema to the database
        /// using a xml data stream
        /// </summary>
        [OperationContract(IsOneWay = true)]
        void UploadRouterDescription(Stream xmlStream);

        [OperationContract]
        bool HasRouterDescription(string routerUniqueId);

        [OperationContract]
        bool HasRouterDescriptionEx(string routerUniqueId, int versionId);

        /// <summary>
        /// returns xml document stream
        /// </summary>
        [OperationContract]
        Stream GetMaxSpecDeviceDom(string rootDeviceTypeId);

        [OperationContract]
        string GetNewerVersion(int versionId);

        [OperationContract]
        ReleaseInfo GetNewerVersion2(int versionId);

        [OperationContract]
        ReleaseInfo GetNewerVersion3(string instanceId, int versionId, bool includeBetaRelease);

        [OperationContract]
        void ReportError(ErrorInfo error);

        [OperationContract]
        void UploadUsageInfo(UsageInfo info);
    }

}
